# coding:utf-8

'''

装饰器

- 一种函数
- 接收函数作为参数
- 可以返回函数
- 接收一个函数，内部对其处理，然后返回一个新函数，动态的增强函数功能
- 将c函数在a函数中执行，在a 函数中可以选择执行或不执行c函数，甚至可以对c函数的结果进行二次加工处理   


案例

装饰器定义：

def outer(func_args):# 外围函数
    def inter(*args,**kwargs):# 内嵌函数：在内嵌函数中，对被执行的函数的返回结果进行二次判断或者加工
        return func_args(*args,**kwargs)
    return inter# 外围函数返回内嵌函数!!!

装饰器使用：

# 方式一：将被调用的函数直接作为参数传入装饰器的外围函数括弧
outer(a())

# 方式二：将装饰器与被调函数绑定在一起 @符号+装饰器函数放在被调用函数定义的上一行，被调用的函数正常定义，只需要在直接调用被执行函数即可
@outer
def a():
    ...
a()

'''

def decoratorFunc(func):
    def inner(*args,**kwargs):
        if "name" in kwargs and kwargs['name']=='fanlihao':
            return 0
        else:
            return 1
    return inner

@decoratorFunc
def cc(*args,**kwargs):
    return 10;

print(cc(1,2,3,4,age=23,name="fanlihao"))


'''

常用的装饰器

1. classmethod:将类函数可以不经过实例化而直接被调用

@classmethod
def func(cls,...):
    do
cls替代普通类函数中的self，cls代表当前操作的是类

在classmethod修饰的函数中，无法调用普通类函数，但是在普通类函数里可以调用被classmethod装饰的类函数
'''

class Test(object):
    def __init__(self,a,b):
        self.a = a
        self.b = b

    @classmethod
    def run(cls):
        print("run")
        # error 被classmethod装饰的函数无法调用普通类内函数
        # cls.dump()

    @staticmethod
    def sleep():
        # error 被staticmethod装饰的函数无cls/self参数，无法调用普通类内函数
        
        print("I want to sleep")

    @property
    def call_me(self):
        print("hello {}".format(self.a))

    def dump(self):
        print("dump")
        # 普通类内函数可以调用被classmethod装饰的函数
        self.run()
        # 普通类内函数可以调用被staticmethod装饰的函数
        self.sleep()

tt = Test(1,2)
# tt.dump()
Test.run()

'''

2. staticmethod 将类函数可以不经过实例化而直接被调用，被该装饰器调用的函数不许传递self或cls，且无法再该函数内调用其他类函数或类变量
@staticmethod
def func(...):
    do
函数体内无cls或self参数
'''
# 被staticmethod装饰的类函数不仅可以由类调用，实例化后的对象也可以调用
tt.sleep()
Test.sleep()

'''

3. property 将类函数的执行免去括弧，类似调用属性

@property
def func(self):
    do

只能有一个self参数

'''

tt.call_me









